//
//  YLVerificationCodeView.swift
//  YLIMKeyBoard
//
//  Created by AlbertYuan on 2023/2/27.
//

import UIKit
import WebKit
import SnapKit

public class YLVerificationCodeView: UIView {

    private lazy var indicator:UIActivityIndicatorView = {
        let indi = UIActivityIndicatorView(frame: .zero)
        indi.startAnimating()
        indi.isHidden = false
        return indi
    }()

    private lazy var webView:WKWebView = {
        // 配置页面自适应缩放
        let js = "var meta = document.createElement('meta'); meta.setAttribute('name', 'viewport'); meta.setAttribute('content', 'width=device-width'); document.getElementsByTagName('head')[0].appendChild(meta)"
        //初始化配置
        let configuration = WKWebViewConfiguration()
        let userScript = WKUserScript(source: js, injectionTime: .atDocumentEnd, forMainFrameOnly: true)
        let usercontroller = WKUserContentController()
        usercontroller.addUserScript(userScript)
        configuration.userContentController = usercontroller
        //注入回调方法
        configuration.userContentController.add(self, name: "getSlideData")
        let webView = WKWebView(frame: .zero, configuration: configuration)
        webView.scrollView.showsVerticalScrollIndicator = false
        webView.scrollView.showsHorizontalScrollIndicator = false
        webView.layer.cornerRadius = 4
        webView.layer.masksToBounds = true
        webView.navigationDelegate = self

        return webView
    }()

    public var callBack:((_ param:[String:String])->())?

    override public func awakeFromNib() {
        super.awakeFromNib()
        setupUI()
        loadHtml()
    }

    public func reloadUI(){
        loadHtml()
    }

}

// MARK: - 设置UI
public extension YLVerificationCodeView {

    private func setupUI() {

        backgroundColor = UIColor(hex: "#E9E9E9")
        layer.cornerRadius = 5
        layer.borderWidth = 0.2
        layer.borderColor = UIColor.lightText.cgColor

        addSubview(webView)
        webView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }

        addSubview(indicator)
        indicator.snp.makeConstraints { make in
            make.width.height.equalTo(20)
            make.center.equalToSuperview()
        }

    }

    private func loadHtml() {
        let path = "file://\(Bundle.main.path(forResource: "sliderCode", ofType: ".html")!)"
        guard let url = URL(string: path) else { return }
        let request = URLRequest(url: url)
        webView.load(request)
    }

}

// MARK: - 对外暴露API
public extension YLVerificationCodeView {
    ///重置滑动验证码状态
    func reset() {
        webView.evaluateJavaScript("reset()", completionHandler: nil)
    }
}


extension YLVerificationCodeView:WKNavigationDelegate{
    /**
        执行层级：①
        webView发起请求之前调用
        allow后才会进行后面的代理方法
        decisionHandler 必须执行
        - parameter webView:          响应webView
        - parameter navigationAction: 包含响应事件的信息对象
        - parameter decisionHandler:  回调block，参数:allow or cancel
        */
    public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
//           debugPrint("class: \(object_getClassName(self))" + #function + "LINE: \(#line)")
           decisionHandler(.allow)
       }
       /**
        执行层级：③
        URL响应正确,接收到相应数据后,决定是否跳转
        decisionHandler 必须执行
        - parameter webView:            响应webView
        - parameter navigationResponse: 请求地址
        - parameter decisionHandler:    回调block，参数:allow or cancel
        */
    public func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
//           debugPrint("class: \(object_getClassName(self))" + #function + "LINE: \(#line)")
           decisionHandler(WKNavigationResponsePolicy.allow)
       }

       /**
        执行层级：②
        允许请求后开始
        - parameter webView:    响应webView
        - parameter navigation: navigation
        */
    public func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
//           debugPrint("class: \(object_getClassName(self))" + #function + "LINE: \(#line)")
       }

       /**
        主机地址被重定向时调用

        - parameter webView:    webView description
        - parameter navigation: navigation description
        */
    public func webView(_ webView: WKWebView, didReceiveServerRedirectForProvisionalNavigation navigation: WKNavigation!) {
           debugPrint("class: \(object_getClassName(self))" + #function + "LINE: \(#line)")
       }
       /**
        执行层级：④
        页面加载失败时调用

        - parameter webView:    响应webView
        - parameter navigation: navigation
        - parameter error:      error
        */
    public func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
           debugPrint(#function + "\nerror: \(error.localizedDescription)")

           reset()
       }
       /**
        执行层级:④
        当内容开始返回时调用

        - parameter webView:    webView description
        - parameter navigation: navigation description
        */
    public func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
           debugPrint("class: \(object_getClassName(self))" + #function + "LINE: \(#line)")

           indicator.isHidden = true
           indicator.stopAnimating()

       }
       /**
        执行层级:⑤
        内容接受完毕后（JS等执行完毕后,在此之前执行 WKUIDelegate 的对应方法）

        - parameter webView:    webView
        - parameter navigation: navigation
        */
    public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
//           debugPrint("class: \(object_getClassName(self))" + #function + "LINE: \(#line)")
       }

       /**
        跳转失败时调用

        - parameter webView:    webView description
        - parameter navigation: navigation description
        - parameter error:      error description
        */
    public func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
//           debugPrint("class: \(object_getClassName(self))" + #function + "LINE: \(#line)")
       }

       /**
        在访问资源的时候，如果服务器返回需要授权(提供一个NSURLCredential对象)

        - parameter webView:           webView description
        - parameter challenge:         challenge description
        - parameter completionHandler:   completionHandler description
        */
    public func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {

           debugPrint("class: \(object_getClassName(self))" + #function + "LINE: \(#line)")
           // 认证服务器证书
           if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
               debugPrint("获得服务端证书认证！")
               completionHandler(.performDefaultHandling, nil)
           }else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodClientCertificate{
               debugPrint("客户端证书认证！")
               //获取客户端证书相关信息
               completionHandler(.useCredential, nil);
           }else {
               debugPrint("其它情况（不接受认证）")
               completionHandler(.cancelAuthenticationChallenge, nil);
           }
       }

       /**
        9.0 later，web内容处理中断时会触发
        - parameter webView: webView description
        */
    public func webViewWebContentProcessDidTerminate(_ webView: WKWebView) {
//          debugPrint("class: \(object_getClassName(self))" + #function + "LINE: \(#line)")
       }
}


///实现WKScriptMessageHandler代理方法
extension YLVerificationCodeView : WKScriptMessageHandler {
    public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        guard let param = message.body as? [String:String] else { return }
        print("param == \(param)")
        if message.name == "getSlideData" {
            callBack?(param)
        }
    }
}

